/*
 An example showing rainbow colours on a 2.2" TFT LCD screen
 and to show basic examples of font use.

 This sketch uses the GLCD, 2, 4, 6 fonts only.

 Make sure all the display driver and pin comnenctions are correct by
 editting the User_Setup.h file in the TFT_eSPI library folder.

 #########################################################################
 ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
 #########################################################################
 */
#include <M5Stack.h>

unsigned long targetTime = 0;
byte red                 = 31;
byte green               = 0;
byte blue                = 0;
byte state               = 0;
unsigned int colour      = red << 11;  // Colour order is RGB 5+6+5 bits each

void setup(void) {
    Serial.begin(9600);
    M5.begin();
    M5.Power.begin();
    // M5.Lcd.setRotation(2);
    M5.Lcd.fillScreen(TFT_BLACK);

    targetTime = millis() + 1000;
}

void loop() {
    if (targetTime < millis()) {
        targetTime = millis() + 10000;

        rainbow_fill();  // Fill the screen with rainbow colours

        // The standard AdaFruit font still works as before
        M5.Lcd.setTextColor(
            TFT_BLACK);  // Background is not defined so it is transparent

        M5.Lcd.setCursor(60, 5);
        M5.Lcd.setTextFont(0);  // Select font 0 which is the Adafruit font
        M5.Lcd.print("Original Adafruit font!");

        // M5.Lcd.drawString("Original Adafruit font!",60,5,1);

        // The new larger fonts do not need to use the .setCursor call, coords
        // are embedded
        M5.Lcd.setTextColor(TFT_BLACK);  // Do not plot the background colour
        // Overlay the black text on top of the rainbow plot (the advantage of
        // not drawing the backgorund colour!)
        M5.Lcd.drawCentreString(
            "Font size 2", 120, 14,
            2);  // Draw text centre at position 120, 14 using font 2
        M5.Lcd.drawCentreString(
            "Font size 4", 120, 30,
            4);  // Draw text centre at position 120, 30 using font 4
        M5.Lcd.drawCentreString(
            "12.34", 120, 54,
            6);  // Draw text centre at position 120, 54 using font 6

        M5.Lcd.drawCentreString(
            "12.34 is in font size 6", 120, 92,
            2);  // Draw text centre at position 120, 92 using font 2
        // Note the x position is the top of the font!

        // draw a floating point number
        float pi      = 3.14159;  // Value to print
        int precision = 3;        // Number of digits after decimal point
        int xpos      = 90;       // x position
        int ypos      = 110;      // y position
        int font      = 2;        // font number 2
        xpos += M5.Lcd.drawFloat(pi, precision, xpos, ypos,
                                 font);  // Draw rounded number and return new
                                         // xpos delta for next print position
        M5.Lcd.drawString(" is pi", xpos, ypos,
                          font);  // Continue printing from new x position

        M5.Lcd.setTextSize(1);  // We are using a size multiplier of 1

        M5.Lcd.setTextColor(TFT_BLACK);  // Set text colour to black, no
                                         // background (so transparent)

        M5.Lcd.setCursor(36, 150,
                         4);  // Set cursor to x = 36, y = 150 and use font 4
        M5.Lcd.println("Transparent...");  // As we use println, the cursor
                                           // moves to the next line

        M5.Lcd.setCursor(30, 175);  // Set cursor to x = 30, y = 175
        M5.Lcd.setTextColor(
            TFT_WHITE,
            TFT_BLACK);  // Set text colour to white and background to black
        M5.Lcd.println("White on black");

        M5.Lcd.setTextFont(4);  // Select font 4 without moving cursor
        M5.Lcd.setCursor(
            50,
            210);  // Set cursor to x = 50, y = 210 without changing the font
        M5.Lcd.setTextColor(TFT_WHITE);
        // By using #TFT print we can use all the formatting features like
        // printing HEX
        M5.Lcd.print(57005, HEX);    // Cursor does no move to next line
        M5.Lcd.println(48879, HEX);  // print and move cursor to next line

        M5.Lcd.setTextColor(TFT_GREEN,
                            TFT_BLACK);  // This time we will use green text on
                                         // a black background
        M5.Lcd.setTextFont(2);           // Select font 2
        // Text will wrap to the next line if needed, by luck it breaks the
        // lines at spaces!
        M5.Lcd.println(
            " Ode to a Small Lump of Green Putty I Found in My Armpit One "
            "Midsummer Morning ");
    }
}

// Fill screen with a rainbow pattern
void rainbow_fill() {
    // The colours and state are not initialised so the start colour changes
    // each time the funtion is called

    for (int i = 319; i > 0; i--) {
        // Draw a vertical line 1 pixel wide in the selected colour
        M5.Lcd.drawFastHLine(0, i, M5.Lcd.width(),
                             colour);  // in this example M5.Lcd.width() returns
                                       // the pixel width of the display
        // This is a "state machine" that ramps up/down the colour brightnesses
        // in sequence
        switch (state) {
            case 0:
                green++;
                if (green == 64) {
                    green = 63;
                    state = 1;
                }
                break;
            case 1:
                red--;
                if (red == 255) {
                    red   = 0;
                    state = 2;
                }
                break;
            case 2:
                blue++;
                if (blue == 32) {
                    blue  = 31;
                    state = 3;
                }
                break;
            case 3:
                green--;
                if (green == 255) {
                    green = 0;
                    state = 4;
                }
                break;
            case 4:
                red++;
                if (red == 32) {
                    red   = 31;
                    state = 5;
                }
                break;
            case 5:
                blue--;
                if (blue == 255) {
                    blue  = 0;
                    state = 0;
                }
                break;
        }
        colour = red << 11 | green << 5 | blue;
    }
}
